import java.io.FileOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class StreamServer extends AbsServer {

    static private final int PORT = 31152;

    private byte[] securityCode = { 0x7f, 0x19, 0x7f, 0x31, 0x44, 0x13, 0x42, 0x15 };
    private ExecutorService threadPool = Executors.newFixedThreadPool(100);

    public StreamServer() {
        super(PORT);
    }

    @Override
    public void service(Socket client) {
        threadPool.submit(new Runnable() {

            @Override
            public void run() {

                FileOutputStream outputFile = null;

                try {
                    var is = client.getInputStream();
                    byte[] header = new byte[8];
                    is.read(header);
                    if (!Arrays.equals(securityCode, header)) {
                        client.shutdownInput();
                        client.close();
                        return;
                    }

                    client.getOutputStream().write(securityCode);
                    client.shutdownOutput();
                    int fileNameIndex = 0;

                    byte[] dataPakcet = new byte[0];
                    
                    System.out.println("开始为" + client.getRemoteSocketAddress().toString() + "服务...");
                    
                    while (true) {
                        int  off = 0;
                        int ret = 0;
                        while(off < 4){
                            ret = is.read(header, off, 4 - off);
                            if(ret == -1){
                                break;
                            }
                            off += ret;
                        }
                        if(ret == -1){
                            break;
                        }
                        System.out.println("接收到一个客户端发来的数据包头");
                        ByteBuffer headBuffer = ByteBuffer.wrap(header, 0, 4);
                        headBuffer.order(ByteOrder.LITTLE_ENDIAN);
                        var len = headBuffer.getInt();
                        
                        if(len == -1){
                            if(outputFile != null){
                                outputFile.close();
                                outputFile = null;
                            }
                            continue;
                        }

                        if (len == -2) {
                            // TODO:: 断开连接
                            break;
                        }
                        System.out.printf("客户端发来%d长度的数据包\n", len);
                        if (dataPakcet.length < len) {
                            dataPakcet = new byte[len];
                        }
 
                        off = 0;
                        ret = 0;
                        while(off < len){
                            ret = is.read(header, off, len - off);
                            if(ret == -1){
                                break;
                            }
                            off += ret;
                        }
                        if(ret == -1){
                            break;
                        }

                        if(outputFile == null){
                            String fileName = String.format("%d.H264", fileNameIndex++);
                            outputFile = new FileOutputStream(fileName);
                        }
                        outputFile.write(dataPakcet, 0, len);
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                    if (outputFile != null){
                        outputFile.close();
                    }

                    client.shutdownInput();
                    client.close();
                    
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                }
			}
            
        });
    }
}
